home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Tools & Apps / Testing & Debugging / Robix V1.0 / SonicDriver.c < prev   
Encoding:
C/C++ Source or Header  |  1991-08-21  |  20.3 KB  |  585 lines  |  [TEXT/MPS ]

  1. /*
  2. *
  3. * Copyright © 1991, Rob Glanville
  4. *
  5. * by Rob Glanville
  6. *
  7. * 7 May 91
  8. *
  9. * SonicDriver.c - SONIC driver for John Galt cards
  10. *
  11. */
  12.  
  13. /************************************* Defines ***********************************************/
  14.  
  15. #include "robix.h"
  16. #include <stdio.h>
  17. #include <OSUtils.h>
  18.  
  19. #define ENet1        0x00
  20. #define ENet2        0x01
  21. #define SONIC        0x900000
  22. #define ENetProm    0x700000
  23. #define ModeSelect    0x600000 // Word read = Smart mode, word write = dumb mode
  24. #define    SlotA        0xfa000000
  25. #define SlotB        0xfb000000
  26.  
  27. /* John Galt card memory offsets */
  28. #define    CDA            0x000100    // CAM descriptor area
  29. #define TDA            0x000110    // Transmit descriptor area
  30. #define RDA            0x000120    // Receiver descriptor area
  31. #define RRA            0x000140    // Receiver resource descriptor area
  32. #define TxBuffer    0x008000    // Transmit buffer
  33. #define RxBuffer    0x00A000    // Receive buffer area 1
  34. #define    UpperBits    0x0000        // Upper address bits
  35. #define FreeMem        0x006000    // All memory above this is free for the taking
  36.  
  37.  
  38. /************************************* Variables *********************************************/
  39.  
  40. UBYTE origMMUMode;
  41. UBYTE globalSlot = ENet1;    /* Set the default slot to the first card */
  42.  
  43. struct {
  44.     UBYTE Destination[6];
  45.     UBYTE Source[6];
  46.     UWORD Length;
  47.     UBYTE Buffer[1500];
  48.     ULONG CRCPad;
  49.     } TxPacket;
  50.  
  51. struct {
  52.     UBYTE Destination[6];
  53.     UBYTE Source[6];
  54.     UWORD Length;
  55.     UBYTE Buffer[1500];
  56.     ULONG CRC;
  57.     } RxPacket;
  58.  
  59. /************************************* Constants *********************************************/
  60.  
  61. UWORD ENet1Address[] = {0x1000,0xe028,0x0877}; /* Slot 1 */
  62. UWORD ENet2Address[] = {0x1000,0xe028,0x0340}; /* Slot 2 */
  63. extern UBYTE *slotBases[6];
  64. UBYTE RegPtr[] = {0,0,1,2,3,4,5,6,7,13,14,20,21,22,23,24,43,33,34,35,36,37,38,39,44,45,46,41,42,40};
  65. struct {
  66.     UBYTE Address[6];
  67.     } Node [3] = {0x10,0x00,0xe0,0x28,0x08,0x77, /* Slot A card */
  68.                   0x10,0x00,0xe0,0x28,0x03,0x40, /* Slot B card */
  69.                   0x10,0x00,0xe0,0x28,0x08,0x77};/* Slot A card */
  70.                   
  71.  
  72. /************************************* Externals *********************************************/
  73.  
  74. extern    UWORD AlterMemory();
  75. extern    UWORD DisplayMemory();
  76. extern    UWORD FillMemory();
  77. extern    void SyntaxError();
  78. extern    void LineIn();
  79. extern    void Upper();
  80. extern    void ScanDelimiters();
  81. extern    void byteout(UBYTE);
  82. extern    UWORD CPointer;
  83. extern    UBYTE CommandLine[0x100];
  84. extern    UBYTE delimiter;
  85. extern    UWORD GetValue();
  86. extern    ULONG number;
  87.  
  88. /************************************* Routines **********************************************/
  89.  
  90. UWORD GetWord(UWORD *Address) {
  91.     UWORD value;
  92.     origMMUMode = true32b;
  93.     SwapMMUMode(&origMMUMode);
  94.     value = *Address;
  95.     SwapMMUMode(&origMMUMode);
  96.     return(value);
  97.     }
  98.     
  99. void PutWord(UWORD *Address,UWORD value) {
  100.     origMMUMode = true32b;
  101.     SwapMMUMode(&origMMUMode);
  102.     *Address = value;
  103.     SwapMMUMode(&origMMUMode);
  104.     }
  105.     
  106. void DisplayInterruptRegister(UBYTE slot) {
  107.     UWORD *regBase,intStatus;
  108.     regBase = (UWORD *)(slotBases[slot] + SONIC);
  109.     intStatus = GetWord(regBase+5);
  110.     PutWord(regBase+5,0xffff); /* Reset the interrupt status */
  111.     if (intStatus & 0x4000) printf("Bus retry occurred\n");
  112.     if (intStatus & 0x2000) printf("CD Heartbeat lost\n");
  113.     if (intStatus & 0x1000) printf("Load CAM done\n");
  114.     if (intStatus & 0x0800) printf("Programmed interrupt\n");
  115.     if (intStatus & 0x0400) printf("Packet received\n");
  116.     if (intStatus & 0x0200) printf("Transmission done\n");
  117.     if (intStatus & 0x0100) printf("Transmit error\n");
  118.     if (intStatus & 0x0080) printf("Timer complete\n");
  119.     if (intStatus & 0x0040) printf("Receive descriptors exhausted\n");
  120.     if (intStatus & 0x0020) printf("Receive buffers exhausted\n");
  121.     if (intStatus & 0x0010) printf("Receive buffer area exceeded\n");
  122.     if (intStatus & 0x0008) printf("CRC tally counter rollover\n");
  123.     if (intStatus & 0x0004) printf("Frame alignment error tally counter rollover\n");
  124.     if (intStatus & 0x0002) printf("Missed packet counter rollover\n");
  125.     if (intStatus & 0x0001) printf("Receive FIFO overrun\n");
  126.     }
  127.  
  128. UWORD WaitForTransmit( UBYTE slot) {
  129.     UWORD *TDAPtr,TxStatus,*regBase;
  130.     ULONG timer;
  131.     /* Build transmit descriptor */
  132.     TDAPtr = (UWORD *)(slotBases[slot] + TDA);
  133.     timer = 0x10000;
  134.     do {
  135.         TxStatus = GetWord(TDAPtr); /* Read the transmitter status */
  136.         } while (((TxStatus & 0x07ff) == 0x0000) && (--timer));
  137.     if (timer) return(False);
  138.     regBase = (UWORD *)(slotBases[slot] + SONIC);
  139.     PutWord(regBase+5,0xffff); /* Reset the interrupt status */
  140.     return(True);
  141.     }
  142.  
  143. /*
  144. * Transmit will load the SONIC registers with the  proper values to start transmission
  145. */
  146. void Transmit(ULONG Buffer, UWORD length, UBYTE slot) {
  147.     UWORD *TDAPtr,*regBase;
  148.     /* Build transmit descriptor */
  149.     length += 14; /* Add in the addresses and length fields */
  150.     TDAPtr = (UWORD *)(slotBases[slot] + TDA);
  151.     PutWord(TDAPtr    ,0x0000);  /* Set status            */
  152.     PutWord(TDAPtr + 1,0x5000);  /* Set configuration    */
  153.     PutWord(TDAPtr + 2,length);  /* Set packet length    */
  154.     PutWord(TDAPtr + 3,0x0001);  /* Set fragment count    */
  155.     PutWord(TDAPtr + 4,Buffer);  /* Set lower address    */
  156.     PutWord(TDAPtr + 5,0x0000);  /* Set upper address    */
  157.     PutWord(TDAPtr + 6,length);  /* Set fragment length    */
  158.     PutWord(TDAPtr + 7,0x0001);  /* Set status            */
  159.     /* Load registers and start the transmission        */
  160.     regBase = (UWORD *)(slotBases[slot] + SONIC);
  161.     PutWord(regBase + 6,0x0000); /* Set upper address    */
  162.     PutWord(regBase + 7,TDA);     /* Set Lower address    */
  163.     PutWord(regBase,0x0002);     /* Start transmission    */
  164.     }
  165.  
  166. void BuildPacket(UBYTE slot,UBYTE station,UWORD length) {
  167.     UWORD index;
  168.     UBYTE *SPtr,*DPtr;
  169.     /* Build a packet in local memory */
  170.     for (index=0;index<6;index++) {
  171.         TxPacket.Destination[index] = Node[station].Address[index];
  172.         TxPacket.Source[index] = Node[slot].Address[index];
  173.         }
  174.     TxPacket.Length = length;
  175.     for (index=0;index<length;index++) {
  176.         TxPacket.Buffer[index] = index;
  177.         }
  178.     /* Copy packet to ENet card memory at 0xFX008000 */
  179.     SPtr = (UBYTE *)&TxPacket;
  180.     DPtr = (UBYTE *)(slotBases[slot] + TxBuffer);
  181.     length += 14; /* Add in the addresses and length fields */
  182.     origMMUMode = true32b;
  183.     SwapMMUMode(&origMMUMode);
  184.     for (index=0;index<length;index++) {
  185.         *DPtr++ = *SPtr++;
  186.         }
  187.     SwapMMUMode(&origMMUMode);
  188.     }
  189.  
  190. void GetPacket(UBYTE slot,UWORD length) {
  191.     UWORD index;
  192.     UBYTE *SPtr,*DPtr;
  193.     /* Copy packet from ENet card memory at 0xFX004000 */
  194.     DPtr = (UBYTE *)&RxPacket;
  195.     SPtr = (UBYTE *)(slotBases[slot] + RxBuffer);
  196.     length += 18; /* Add in the addresses, length and CRC fields */
  197.     origMMUMode = true32b;
  198.     SwapMMUMode(&origMMUMode);
  199.     for (index=0;index<length;index++) {
  200.         *DPtr++ = *SPtr++;
  201.         }
  202.     SwapMMUMode(&origMMUMode);
  203.     }
  204.  
  205. UWORD ComparePackets(UWORD length) {
  206.     UBYTE failed;
  207.     UWORD index;
  208.     UBYTE *SPtr,*DPtr;
  209.     failed = False;
  210.     SPtr = (UBYTE *)&TxPacket.Buffer;
  211.     DPtr = (UBYTE *)&RxPacket.Buffer;
  212.     for (index=0;index<length;index++) {
  213.         if (*DPtr++ != *SPtr++) {
  214.             failed = True;
  215.             break;
  216.             }
  217.         }
  218.     if (failed) {
  219.         printf("The Buffers miscompared\n");
  220.         return(True);
  221.         }
  222.     else return(False);
  223.     }
  224.  
  225. /*
  226. * Transmit packet will build a packet in memory and transmit it
  227. */
  228. void TestTransmit(UBYTE slot, UBYTE station, UWORD length) {
  229.     UWORD TxError;
  230.     BuildPacket(slot,station,length);
  231.     Transmit(TxBuffer,length,slot);
  232.     TxError = WaitForTransmit(slot);
  233.     if (TxError) {
  234.         printf("Transmission error, checking status..\n");
  235.         DisplayInterruptRegister(slot);
  236.         }
  237.     }
  238.  
  239. UWORD WaitForReceive( UBYTE slot ) {
  240.     UWORD *RDAPtr,RxStatus,*regBase;
  241.     ULONG timer;
  242.     RDAPtr = (UWORD *)(slotBases[slot] + RDA); /* Point to RDA        */
  243.     timer = 0x10000;
  244.     do {
  245.         RxStatus = GetWord(RDAPtr); /* Read the receiver status */
  246.         } while (((RxStatus & 0x01ff) == 0x0000) && (--timer));
  247.     if (timer) return(False);
  248.     regBase = (UWORD *)(slotBases[slot] + SONIC);
  249.     PutWord(regBase+5,0xffff); /* Reset the interrupt status */
  250.     return(True);
  251.     }
  252.  
  253. void Receive(ULONG buffer, UWORD length, UBYTE slot) {
  254.     UWORD *RDAPtr,*RRAPtr,*regBase;
  255.     
  256.     /* Build the resource descriptor area                            */
  257.     length += 18; /* Add in the addresses, length and CRC fields */
  258.     RRAPtr = (UWORD *)(slotBases[slot] + RRA); /* Point to RRA        */
  259.     PutWord(RRAPtr    ,buffer);  /* Set lower address                */
  260.     PutWord(RRAPtr + 1,0x0000);  /* Set upper address                */
  261.     PutWord(RRAPtr + 2,length);  /* Set lower length                */
  262.     PutWord(RRAPtr + 3,0x0000);  /* Set upper length                */
  263.     
  264.     /* Build receiver descriptor                                    */
  265.     RDAPtr = (UWORD *)(slotBases[slot] + RDA); /* Point to RDA        */
  266.     PutWord(RDAPtr    ,0x0000);  /* Set status                        */
  267.     PutWord(RDAPtr + 1,0x0000);  /* Set packet length                */
  268.     PutWord(RDAPtr + 2,0x0000);  /* Set lower address                */
  269.     PutWord(RDAPtr + 3,0x0000);  /* Set upper address                */
  270.     PutWord(RDAPtr + 4,0x0000);  /* Set Sequence number                */
  271.     PutWord(RDAPtr + 5,0x0001);  /* Set link                        */
  272.     PutWord(RDAPtr + 6,0xffff);  /* Set in use                        */
  273.     
  274.     /* Load registers and get read for reception                    */
  275.     regBase = (UWORD *)(slotBases[slot] + SONIC); /* Point to SONIC    */
  276.     PutWord(regBase + 13,0x0000); /* Set upper address                */
  277.     PutWord(regBase + 14,RDA);      /* Set Lower address                */
  278.     PutWord(regBase + 20,0x0000); /* Set upper address                */
  279.     PutWord(regBase + 21,RRA);    /* Set Resource start address        */
  280.     PutWord(regBase + 22,RRA+4);  /* Set Resource end address        */
  281.     PutWord(regBase + 23,RRA);    /* Set Resource read register        */
  282.     PutWord(regBase + 24,RRA+4);  /* Set Resource write register    */
  283.     PutWord(regBase + 43,0x0000); /* Set Receive sequence counter    */
  284.     PutWord(regBase,0x0100);      /* Read RRA            */
  285.     PutWord(regBase,0x0008);      /* Start receiving    */
  286.     }
  287.  
  288. void SONICStatus() {
  289.     UBYTE slot;
  290.     UWORD *regBase;
  291.     ULONG slotBase;
  292.     if (GetValue()) slot = number;
  293.     else slot = ENet1;
  294.     if (slot < ENet1) slot = ENet1;
  295.     if (slot > ENet2) slot = ENet2;
  296.     slotBase = (slotBases[slot] + SONIC);
  297.     regBase = (UWORD *)slotBase;
  298.     printf(" 1) Command                             %lX = %04X\n",(regBase   ),GetWord(regBase   ));
  299.     printf(" 2) Configuration                       %lX = %04X\n",(regBase+1 ),GetWord(regBase+1 ));
  300.     printf(" 3) Rx Control                          %lX = %04X\n",(regBase+2 ),GetWord(regBase+2 ));
  301.     printf(" 4) Tx Control                          %lX = %04X\n",(regBase+3 ),GetWord(regBase+3 ));
  302.     printf(" 5) Interrupt Mask                      %lX = %04X\n",(regBase+4 ),GetWord(regBase+4 ));
  303.     printf(" 6) Interrupt status                    %lX = %04X\n",(regBase+5 ),GetWord(regBase+5 ));
  304.     printf(" 7) Upper transmit descriptor address   %lX = %04X\n",(regBase+6 ),GetWord(regBase+6 ));
  305.     printf(" 8) Current transmit descriptor address %lX = %04X\n",(regBase+7 ),GetWord(regBase+7 ));
  306.     printf(" 9) Upper receiver descriptor address   %lX = %04X\n",(regBase+13),GetWord(regBase+13));
  307.     printf("10) Current receiver descriptor address %lX = %04X\n",(regBase+14),GetWord(regBase+14));
  308.     printf("11) Upper receiver resource address     %lX = %04X\n",(regBase+20),GetWord(regBase+20));
  309.     printf("12) Resource start address              %lX = %04X\n",(regBase+21),GetWord(regBase+21));
  310.     printf("13) Resource end address                %lX = %04X\n",(regBase+22),GetWord(regBase+22));
  311.     printf("14) Resource read                       %lX = %04X\n",(regBase+23),GetWord(regBase+23));
  312.     printf("15) Resource write                      %lX = %04X\n",(regBase+24),GetWord(regBase+24));
  313.     printf("16) Receive sequence counter            %lX = %04X\n",(regBase+43),GetWord(regBase+43));
  314.     printf("17) CAM entry pointer                   %lX = %04X\n",(regBase+33),GetWord(regBase+33));
  315.     printf("18) CAM address port 2                  %lX = %04X\n",(regBase+34),GetWord(regBase+34));
  316.     printf("19) CAM address port 1                  %lX = %04X\n",(regBase+35),GetWord(regBase+35));
  317.     printf("20) CAM address port 0                  %lX = %04X\n",(regBase+36),GetWord(regBase+36));
  318.     printf("21) CAM Enable                          %lX = %04X\n",(regBase+37),GetWord(regBase+37));
  319.     printf("22) CAM descriptor pointer              %lX = %04X\n",(regBase+38),GetWord(regBase+38));
  320.     printf("23) CAM descriptor count                %lX = %04X\n",(regBase+39),GetWord(regBase+39));
  321.     printf("24) CRC error tally counter             %lX = %04X\n",(regBase+44),GetWord(regBase+44));
  322.     printf("25) Frame alignment error tally         %lX = %04X\n",(regBase+45),GetWord(regBase+45));
  323.     printf("26) Missed packet tally                 %lX = %04X\n",(regBase+46),GetWord(regBase+46));
  324.     printf("27) Watchdog timer 0                    %lX = %04X\n",(regBase+41),GetWord(regBase+41));
  325.     printf("28) Watchdog timer 1                    %lX = %04X\n",(regBase+42),GetWord(regBase+42));
  326.     printf("29) Silicon revision register           %lX = %04X\n",(regBase+40),GetWord(regBase+40));
  327.     }
  328.  
  329. /*
  330. * Display Sonic Registers will display or change one register at a time using logical references
  331. * as outlined in the SONICStatus routine.
  332. * The syntax is;
  333. *  g [ register ] [ value ] <cr> , Set register to value
  334. *  g [ register ] <cr> , Display register
  335. *  g <cr> , Display last register
  336. * This routine plays a trick on the hex register pointer to make it appear to be decimal
  337. * so hex number between 'a' and 'f' and also '1a' and '1f' are valid but should not be used
  338. */
  339. UBYTE RegisterPointer = 0;
  340. void DisplaySonicRegister() {
  341.     UBYTE setRegister;
  342.     UWORD *regBase,value;
  343.     if (GetValue()) RegisterPointer = number;
  344.     if (RegisterPointer > 0x1f) RegisterPointer -= 12; // Adjust for decimal like index, make 0x20 into 20
  345.     else if (RegisterPointer > 0x0f) RegisterPointer -= 6;  // Adjust for decimal like index, make 0x10 into 10
  346.     if (GetValue()) {
  347.         value = number;
  348.         setRegister = True;
  349.         }
  350.     else setRegister = False;
  351.     regBase = (UWORD *)(slotBases[globalSlot] + SONIC + (2 * RegPtr[RegisterPointer]));
  352.     if (setRegister) {
  353.         PutWord(regBase,value);
  354.         }
  355.     else {
  356.         value = GetWord(regBase);
  357.         printf("%lX = %04X\n",regBase,value);
  358.         }
  359.     }
  360.  
  361. /*
  362. * Load CAM will place the Ethernet address into the SONIC registers
  363. */
  364. void LoadCAM(UBYTE slot) {
  365.     UWORD *CDABase,*regBase,*ENetPromBase,intStatus,AddrWord,AddrWordH,AddrWordL;
  366.     ULONG timer;
  367.     regBase = (UWORD *)(slotBases[slot] + SONIC);
  368.     PutWord(regBase,0x0085);    /* Reset and stop operations */
  369.     PutWord(regBase+1,0x0B03);    /* Set the configuration register */
  370.     PutWord(regBase,0x0000);    /* Remove the reset, stop operations */
  371.     CDABase = (UWORD *)(slotBases[slot] + CDA);
  372.     ENetPromBase = (UWORD *)(slotBases[slot] + ENetProm);
  373.     PutWord(CDABase,0x0000);    /* Set the CAM entry pointer */
  374.     AddrWordH = GetWord(ENetPromBase + 1);
  375.     AddrWordL = GetWord(ENetPromBase + 0);
  376.     AddrWord = ((AddrWordH << 8) & 0xff00) + (AddrWordL & 0x00ff);
  377.     PutWord(CDABase+1,AddrWord);
  378.     AddrWordH = GetWord(ENetPromBase + 3);
  379.     AddrWordL = GetWord(ENetPromBase + 2);
  380.     AddrWord = ((AddrWordH << 8) & 0xff00) + (AddrWordL & 0x00ff);
  381.     PutWord(CDABase+2,AddrWord);
  382.     AddrWordH = GetWord(ENetPromBase + 5);
  383.     AddrWordL = GetWord(ENetPromBase + 4);
  384.     AddrWord = ((AddrWordH << 8) & 0xff00) + (AddrWordL & 0x00ff);
  385.     PutWord(CDABase+3,AddrWord);
  386.     PutWord(CDABase+4,0x0001);    /* Set the CAM descriptor count */
  387.     PutWord(regBase+20,0x0000);    /* Set upper pointer */
  388.     PutWord(regBase+38,CDA);    /* Set lower pointer */
  389.     PutWord(regBase+39,0x0001);    /* Set descriptor count */
  390.     PutWord(regBase,0x0200);    /* Set load CAM command */
  391.     timer = 0x80000;
  392.     do {
  393.         intStatus = GetWord(regBase+5); /* Read the interrupt status */
  394.         } while (((intStatus & 0x1000) != 0x1000) && (--timer));
  395.     }
  396.  
  397. /*
  398. * This will send a packet of data from one John Galt Ethernet card to another John Galt card
  399. * and compare the results.
  400. * 1) Build a packet in memory and copy it one of the John Galt cards (first card)
  401. * 2) Tell the second card to get ready for reception
  402. * 3) Tell the first card to transmit
  403. * 4) Wait for first card transmit done and report errors
  404. * 5) Wait for second card receive done and report errors
  405. * 6) Copy packet from second card to main memory
  406. * 7) Compare the two packets and report errors
  407. * 8) Switch source with destination and repeat until loop count is zero
  408. */
  409. void CardToCardTest() {
  410.     UBYTE sourceSlot;
  411.     UBYTE destinationSlot;
  412.     UBYTE temporarySlot;
  413.     UWORD length;
  414.     ULONG loopCount;
  415.     if (GetValue()) loopCount = number;
  416.     else loopCount = 1; /* Minimum count */
  417.     if (loopCount == 0) loopCount = 1;
  418.     if (GetValue()) sourceSlot = number;
  419.     else sourceSlot = ENet1;
  420.     if (GetValue()) destinationSlot = number;
  421.     else destinationSlot = ENet2;
  422.     if (GetValue()) length = number;
  423.     else length = 1500; /* Maximum packet size */
  424.     if (length < 64) length = 50; /* Minimum length for data field */
  425.     else if (length > 1500) length = 1500; /* Maximum data length */
  426.     if (sourceSlot < 1) sourceSlot = 1;
  427.     else if (sourceSlot > 2) sourceSlot = 2;
  428.     if (destinationSlot < 1) destinationSlot = 1;
  429.     else if (destinationSlot > 2) destinationSlot = 2;
  430.     if (sourceSlot == destinationSlot) {
  431.         sourceSlot = 1;
  432.         destinationSlot = 2;
  433.         }
  434.         
  435.     /* Build the transmit buffer and send it off to the transmit card */
  436.     BuildPacket(sourceSlot,destinationSlot,length);      /* 1) Build a source packet for both cards */
  437.     BuildPacket(destinationSlot,sourceSlot,length);      /* 1) Build a source packet for both cards */
  438.     while (loopCount--) {
  439.         Receive(RxBuffer,length,destinationSlot);      /* 2) Start Receiver */
  440.         Transmit(TxBuffer,length,sourceSlot);          /* 3) Start Transmiter */
  441.         if (WaitForTransmit(sourceSlot)) {              /* 4) Wait for transmit */
  442.             DisplayInterruptRegister(sourceSlot);      /* 4) Report transmit errors */
  443.             break;
  444.             }
  445.         if (WaitForReceive(destinationSlot)) {          /* 5) Wait for receive */
  446.             DisplayInterruptRegister(destinationSlot);/* 5) Report receive errors */
  447.             break;
  448.             }
  449.         GetPacket(destinationSlot,length);              /* 6) Copy packet from Enet card to Mac memeory */
  450.         if (ComparePackets(length)) break;              /* 7) Compare data and report errors */
  451.         temporarySlot = sourceSlot;                      /* 8) Switch source and destination */
  452.         sourceSlot = destinationSlot;
  453.         destinationSlot = temporarySlot;
  454.         }
  455.     }
  456.  
  457. /*********************************** Command Loop ********************************************/
  458.  
  459. void SONICHelp() {
  460.     printf("?) Print this menu\n");
  461.     printf("A) Alter memory\n");
  462.     printf("B) Display interrupt status\n");
  463.     printf("C) Send packets from card to card\n");
  464.     printf("D) Display memory\n");
  465.     printf("F) Fill memory\n");
  466.     printf("G) Display or modify SONIC register\n");
  467.     printf("L) Load CAM\n");
  468.     printf("Q) Quit\n");
  469.     printf("R) Receive\n");
  470.     printf("S) SONIC status\n");
  471.     printf("T) Transmit 1 to 2\n");
  472.     printf("U) Transmit 2 to 1\n");
  473.     printf("V) Transmit both at once\n");
  474.     printf("X) Exit this menu\n");
  475.     }
  476.  
  477. /*
  478. * if ExitMode = 'Q' then quit program, if 'X' then return to main menu
  479. */
  480. UBYTE SONICMenu() {
  481.     UBYTE Exit,ExitMode,slot;
  482.     ULONG index,count;
  483.     delimiter = CR;
  484.     Exit = False;
  485.     printf("SONIC control menu\n");
  486.     while (!Exit) {
  487.         if (delimiter == CR) putchar('*');
  488.         LineIn();
  489.         ScanDelimiters(); /* Point to first non Blank */
  490.         Upper(&CommandLine[CPointer]);
  491.         switch(CommandLine[CPointer++]) {
  492.             case '?' :
  493.                 SONICHelp();
  494.                 break;
  495.             case CR :
  496.                 break;
  497.             case 'A' :
  498.                 if (AlterMemory()) SyntaxError();
  499.                 break;
  500.             case 'B' :
  501.                 if (GetValue()) slot = number;
  502.                 else slot = ENet1;
  503.                 if (slot < ENet1) slot = ENet1;
  504.                 if (slot > ENet2) slot = ENet2;
  505.                 DisplayInterruptRegister(slot);
  506.                 break;
  507.             case 'C' :
  508.                 CardToCardTest();
  509.                 break;
  510.             case 'D' :
  511.                 if (DisplayMemory()) SyntaxError();
  512.                 break;
  513.             case 'F' :
  514.                 if (FillMemory()) SyntaxError();
  515.                 break;
  516.             case 'G' :
  517.                 if (GetValue()) slot = number;
  518.                 else slot = ENet1;
  519.                 if (slot < ENet1) slot = ENet1;
  520.                 if (slot > ENet2) slot = ENet2;
  521.                 DisplaySonicRegister(slot);
  522.                 break;
  523.             case 'L' :
  524.                 if (GetValue()) slot = number;
  525.                 else slot = ENet1;
  526.                 if (slot < ENet1) slot = ENet1;
  527.                 if (slot > ENet2) slot = ENet2;
  528.                 LoadCAM(slot);
  529.                 break;
  530.             case 'Q' :
  531.                 Exit = True;
  532.                 ExitMode = 'Q';
  533.                 printf("Bye...\n");
  534.                 break;
  535.             case 'R' :
  536.                 if (GetValue()) slot = number;
  537.                 else slot = ENet1;
  538.                 if (slot < ENet1) slot = ENet1;
  539.                 if (slot > ENet2) slot = ENet2;
  540.                 Receive(RxBuffer,0x600,slot);
  541.                 break;
  542.             case 'S' :
  543.                 SONICStatus();
  544.                 break;
  545.             case 'T' :
  546.                 if (GetValue()) count = number;
  547.                 else count = 1;
  548.                 if (count == 0) count = 1;
  549.                 for (index=0;index<count;index++) {
  550.                     TestTransmit(ENet1,ENet2,736);
  551.                     }
  552.                 break;
  553.             case 'U' :
  554.                 if (GetValue()) count = number;
  555.                 else count = 1;
  556.                 if (count == 0) count = 1;
  557.                 for (index=0;index<count;index++) {
  558.                     TestTransmit(ENet2,ENet1,926);
  559.                     }
  560.                 break;
  561.             case 'V' :
  562.                 if (GetValue()) count = number;
  563.                 else count = 1;
  564.                 if (count == 0) count = 1;
  565.                 for (index=0;index<count;index++) {
  566.                     TestTransmit(ENet1,ENet2,676);
  567.                     TestTransmit(ENet2,ENet1,856);
  568.                     }
  569.                 break;
  570.             case 'X' :
  571.                 Exit = True;
  572.                 ExitMode = 'X';
  573.                 printf("See ya...\n");
  574.                 break;
  575.             default :
  576.                 printf("Unknown SONIC menu command, %2X\n",CommandLine[--CPointer]);
  577.                 CPointer++;
  578.                 delimiter = CR;
  579.                 break;
  580.             }
  581.         }
  582.     return(ExitMode);
  583.     }
  584.     
  585.